home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / ice / pisces / flex / gen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  24.7 KB  |  1,092 lines

  1. /* gen - actual generation (writing) of flex scanners */
  2.  
  3. /*
  4.  * Copyright (c) 1989 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant to
  11.  * contract no. DE-AC03-76SF00098 between the United States Department of
  12.  * Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted
  15.  * provided that the above copyright notice and this paragraph are
  16.  * duplicated in all such forms and that any documentation,
  17.  * advertising materials, and other materials related to such
  18.  * distribution and use acknowledge that the software was developed
  19.  * by the University of California, Berkeley.  The name of the
  20.  * University may not be used to endorse or promote products derived
  21.  * from this software without specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26.  
  27. #ifndef lint
  28.  
  29. static char copyright[] =
  30.     "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  31. static char CR_continuation[] = "@(#) All rights reserved.\n";
  32.  
  33. static char rcsid[] =
  34.     "@(#) $Header: /tan/u1/neath/pisces/flex/RCS/gen.c,v 1.1 90/05/15 13:13:41 neath Exp $ (LBL)";
  35.  
  36. #endif
  37.  
  38. #include "flexdef.h"
  39.  
  40.  
  41. static int indent_level = 0; /* each level is 4 spaces */
  42.  
  43. #define indent_up() (++indent_level)
  44. #define indent_down() (--indent_level)
  45. #define set_indent(indent_val) indent_level = indent_val
  46.  
  47.  
  48.  
  49. /* indent to the current level */
  50.  
  51. do_indent()
  52.  
  53.     {
  54.     register int i = indent_level * 4;
  55.  
  56.     while ( i >= 8 )
  57.     {
  58.     putchar( '\t' );
  59.     i -= 8;
  60.     }
  61.     
  62.     while ( i > 0 )
  63.     {
  64.     putchar( ' ' );
  65.     --i;
  66.     }
  67.     }
  68.  
  69.  
  70. /* generate the code to keep backtracking information */
  71.  
  72. gen_backtracking()
  73.  
  74.     {
  75.     if ( reject || num_backtracking == 0 )
  76.     return;
  77.  
  78.     if ( fullspd )
  79.     indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  80.     else
  81.     indent_puts( "if ( yy_accept[yy_current_state] )" );
  82.  
  83.     indent_up();
  84.     indent_puts( "{" );
  85.     indent_puts( "yy_last_accepting_state = yy_current_state;" );
  86.     indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  87.     indent_puts( "}" );
  88.     indent_down();
  89.     }
  90.  
  91.  
  92. /* generate the code to perform the backtrack */
  93.  
  94. gen_bt_action()
  95.  
  96.     {
  97.     if ( reject || num_backtracking == 0 )
  98.     return;
  99.  
  100.     set_indent( 4 );
  101.  
  102.     indent_puts( "case 0: /* must backtrack */" );
  103.     indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  104.     indent_puts( "*yy_cp = yy_hold_char;" );
  105.  
  106.     if ( fullspd || fulltbl )
  107.     indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  108.     else
  109.     /* backtracking info for compressed tables is taken \after/
  110.      * yy_cp has been incremented for the next state
  111.      */
  112.     indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  113.  
  114.     indent_puts( "yy_current_state = yy_last_accepting_state;" );
  115.     indent_puts( "continue; /* go to \"YY_DO_BEFORE_ACTION\" */" );
  116.     putchar( '\n' );
  117.  
  118.     set_indent( 0 );
  119.     }
  120.  
  121.  
  122. /* genctbl - generates full speed compressed transition table
  123.  *
  124.  * synopsis
  125.  *     genctbl();
  126.  */
  127.  
  128. genctbl()
  129.  
  130.     {
  131.     register int i;
  132.     int end_of_buffer_action = num_rules + 1;
  133.  
  134.     /* table of verify for transition and offset to next state */
  135.     printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  136.         tblend + numecs + 1 );
  137.     printf( "    {\n" );
  138.     
  139.     /* We want the transition to be represented as the offset to the
  140.      * next state, not the actual state number, which is what it currently is.
  141.      * The offset is base[nxt[i]] - base[chk[i]].  That's just the
  142.      * difference between the starting points of the two involved states
  143.      * (to - from).
  144.      *
  145.      * first, though, we need to find some way to put in our end-of-buffer
  146.      * flags and states.  We do this by making a state with absolutely no
  147.      * transitions.  We put it at the end of the table.
  148.      */
  149.     /* at this point, we're guaranteed that there's enough room in nxt[]
  150.      * and chk[] to hold tblend + numecs entries.  We need just two slots.
  151.      * One for the action and one for the end-of-buffer transition.  We
  152.      * now *assume* that we're guaranteed the only character we'll try to
  153.      * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to
  154.      * make sure there's room for jam entries for other characters.
  155.      */
  156.  
  157.     base[lastdfa + 1] = tblend + 2;
  158.     nxt[tblend + 1] = end_of_buffer_action;
  159.     chk[tblend + 1] = numecs + 1;
  160.     chk[tblend + 2] = 1; /* anything but EOB */
  161.     nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */
  162.  
  163.     /* make sure every state has a end-of-buffer transition and an action # */
  164.     for ( i = 0; i <= lastdfa; ++i )
  165.     {
  166.     register int anum = dfaacc[i].dfaacc_state;
  167.  
  168.     chk[base[i]] = EOB_POSITION;
  169.     chk[base[i] - 1] = ACTION_POSITION;
  170.     nxt[base[i] - 1] = anum;    /* action number */
  171.     }
  172.  
  173.     dataline = 0;
  174.     datapos = 0;
  175.  
  176.     for ( i = 0; i <= tblend; ++i )
  177.     {
  178.     if ( chk[i] == EOB_POSITION )
  179.         transition_struct_out( 0, base[lastdfa + 1] - i );
  180.  
  181.     else if ( chk[i] == ACTION_POSITION )
  182.         transition_struct_out( 0, nxt[i] );
  183.  
  184.     else if ( chk[i] > numecs || chk[i] == 0 )
  185.         transition_struct_out( 0, 0 );        /* unused slot */
  186.  
  187.     else    /* verify, transition */
  188.         transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) );
  189.     }
  190.  
  191.  
  192.     /* here's the final, end-of-buffer state */
  193.     transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  194.     transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  195.  
  196.     printf( "    };\n" );
  197.     printf( "\n" );
  198.  
  199.     /* table of pointers to start states */
  200.     printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  201.     lastsc * 2 + 1 );
  202.     printf( "    {\n" );
  203.  
  204.     for ( i = 0; i <= lastsc * 2; ++i )
  205.     printf( "    &yy_transition[%d],\n", base[i] );
  206.  
  207.     printf( "    };\n" );
  208.  
  209.     if ( useecs )
  210.     genecs();
  211.     }
  212.  
  213.  
  214. /* generate equivalence-class tables */
  215.  
  216. genecs()
  217.  
  218.     {
  219.     register int i, j;
  220.     static char C_char_decl[] = "static const char %s[%d] =\n    {   0,\n";
  221.     int numrows;
  222.     char clower();
  223.  
  224.     printf( C_char_decl, ECARRAY, CSIZE + 1 );
  225.  
  226.     for ( i = 1; i <= CSIZE; ++i )
  227.     {
  228.     if ( caseins && (i >= 'A') && (i <= 'Z') )
  229.         ecgroup[i] = ecgroup[clower( i )];
  230.  
  231.     ecgroup[i] = abs( ecgroup[i] );
  232.     mkdata( ecgroup[i] );
  233.     }
  234.  
  235.     dataend();
  236.  
  237.     if ( trace )
  238.     {
  239.     fputs( "\n\nEquivalence Classes:\n\n", stderr );
  240.  
  241.     numrows = (CSIZE + 1) / 8;
  242.  
  243.     for ( j = 1; j <= numrows; ++j )
  244.         {
  245.         for ( i = j; i <= CSIZE; i = i + numrows )
  246.         {
  247.         char *readable_form();
  248.  
  249.         fprintf( stderr, "%4s = %-2d",
  250.              readable_form( i ), ecgroup[i] );
  251.  
  252.         putc( ' ', stderr );
  253.         }
  254.  
  255.         putc( '\n', stderr );
  256.         }
  257.     }
  258.     }
  259.  
  260.  
  261. /* generate the code to find the action number */
  262.  
  263. gen_find_action()
  264.  
  265.     {
  266.     if ( fullspd )
  267.     indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
  268.  
  269.     else if ( fulltbl )
  270.     indent_puts( "yy_act = yy_accept[yy_current_state];" );
  271.  
  272.     else if ( reject )
  273.     {
  274.     indent_puts( "yy_current_state = *--yy_state_ptr;" );
  275.     indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  276.  
  277.     puts( "find_rule: /* we branch to this label when backtracking */" );
  278.  
  279.     indent_puts( "for ( ; ; ) /* until we find what rule we matched */" );
  280.  
  281.     indent_up();
  282.  
  283.     indent_puts( "{" );
  284.  
  285.     indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  286.     indent_up();
  287.     indent_puts( "{" );
  288.     indent_puts( "yy_act = yy_acclist[yy_lp];" );
  289.  
  290.     if ( variable_trailing_context_rules )
  291.         {
  292.         indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  293.         indent_puts( "     yy_looking_for_trail_begin )" );
  294.         indent_up();
  295.         indent_puts( "{" );
  296.  
  297.         indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" );
  298.         indent_up();
  299.         indent_puts( "{" );
  300.         indent_puts( "yy_looking_for_trail_begin = 0;" );
  301.         indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
  302.         indent_puts( "break;" );
  303.         indent_puts( "}" );
  304.         indent_down();
  305.  
  306.         indent_puts( "}" );
  307.         indent_down();
  308.  
  309.         indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
  310.         indent_up();
  311.         indent_puts( "{" );
  312.         indent_puts(
  313.         "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
  314.         indent_puts(
  315.         "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
  316.  
  317.         if ( real_reject )
  318.         {
  319.         /* remember matched text in case we back up due to REJECT */
  320.         indent_puts( "yy_full_match = yy_cp;" );
  321.         indent_puts( "yy_full_state = yy_state_ptr;" );
  322.         indent_puts( "yy_full_lp = yy_lp;" );
  323.         }
  324.  
  325.         indent_puts( "}" );
  326.         indent_down();
  327.  
  328.         indent_puts( "else" );
  329.         indent_up();
  330.         indent_puts( "{" );
  331.         indent_puts( "yy_full_match = yy_cp;" );
  332.         indent_puts( "yy_full_state = yy_state_ptr;" );
  333.         indent_puts( "yy_full_lp = yy_lp;" );
  334.         indent_puts( "break;" );
  335.         indent_puts( "}" );
  336.         indent_down();
  337.  
  338.         indent_puts( "++yy_lp;" );
  339.         indent_puts( "goto find_rule;" );
  340.         }
  341.  
  342.     else
  343.         {
  344.         /* remember matched text in case we back up due to trailing context
  345.          * plus REJECT
  346.          */
  347.         indent_up();
  348.         indent_puts( "{" );
  349.         indent_puts( "yy_full_match = yy_cp;" );
  350.         indent_puts( "break;" );
  351.         indent_puts( "}" );
  352.         indent_down();
  353.         }
  354.  
  355.     indent_puts( "}" );
  356.     indent_down();
  357.  
  358.     indent_puts( "--yy_cp;" );
  359.  
  360.     /* we could consolidate the following two lines with those at
  361.      * the beginning, but at the cost of complaints that we're
  362.      * branching inside a loop
  363.      */
  364.     indent_puts( "yy_current_state = *--yy_state_ptr;" );
  365.     indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  366.  
  367.     indent_puts( "}" );
  368.  
  369.     indent_down();
  370.     }
  371.  
  372.     else
  373.     /* compressed */
  374.     indent_puts( "yy_act = yy_accept[yy_current_state];" );
  375.     }
  376.  
  377.  
  378. /* genftbl - generates full transition table
  379.  *
  380.  * synopsis
  381.  *     genftbl();
  382.  */
  383.  
  384. genftbl()
  385.  
  386.     {
  387.     register int i;
  388.     int end_of_buffer_action = num_rules + 1;
  389.  
  390.     /* *everything* is done in terms of arrays starting at 1, so provide
  391.      * a null entry for the zero element of all C arrays
  392.      */
  393.     static char C_short_decl[] =
  394.     "static const short int %s[%d] =\n    {   0,\n";
  395.  
  396.     printf( C_short_decl, ALIST, lastdfa + 1 );
  397.  
  398.  
  399.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  400.  
  401.     for ( i = 1; i <= lastdfa; ++i )
  402.     {
  403.     register int anum = dfaacc[i].dfaacc_state;
  404.  
  405.     mkdata( anum );
  406.  
  407.     if ( trace && anum )
  408.         fprintf( stderr, "state # %d accepts: [%d]\n", i, anum );
  409.     }
  410.  
  411.     dataend();
  412.  
  413.     if ( useecs )
  414.     genecs();
  415.  
  416.     /* don't have to dump the actual full table entries - they were created
  417.      * on-the-fly
  418.      */
  419.     }
  420.  
  421.  
  422. /* generate the code to find the next compressed-table state */
  423.  
  424. gen_next_compressed_state()
  425.  
  426.     {
  427.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  428.  
  429.     indent_put2s( "register char yy_c = %s;", char_map );
  430.  
  431.     /* save the backtracking info \before/ computing the next state
  432.      * because we always compute one more state than needed - we
  433.      * always proceed until we reach a jam state
  434.      */
  435.     gen_backtracking();
  436.  
  437.     indent_puts(
  438.     "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
  439.     indent_up();
  440.     indent_puts( "{" );
  441.     indent_puts( "yy_current_state = yy_def[yy_current_state];" );
  442.  
  443.     if ( usemecs )
  444.     {
  445.     /* we've arrange it so that templates are never chained
  446.      * to one another.  This means we can afford make a
  447.      * very simple test to see if we need to convert to
  448.      * yy_c's meta-equivalence class without worrying
  449.      * about erroneously looking up the meta-equivalence
  450.      * class twice
  451.      */
  452.     do_indent();
  453.     /* lastdfa + 2 is the beginning of the templates */
  454.     printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
  455.  
  456.     indent_up();
  457.     indent_puts( "yy_c = yy_meta[yy_c];" );
  458.     indent_down();
  459.     }
  460.  
  461.     indent_puts( "}" );
  462.     indent_down();
  463.  
  464.     indent_puts(
  465.     "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" );
  466.     }
  467.  
  468.  
  469. /* generate the code to find the next match */
  470.  
  471. gen_next_match()
  472.  
  473.     { /* NOTE - changes in here should be reflected in get_next_state() */
  474.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  475.     char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp";
  476.     
  477.     if ( fulltbl )
  478.     {
  479.     indent_put2s(
  480.         "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
  481.         char_map );
  482.  
  483.     indent_up();
  484.  
  485.     if ( num_backtracking > 0 )
  486.         {
  487.         indent_puts( "{" );
  488.         gen_backtracking();
  489.         putchar( '\n' );
  490.         }
  491.  
  492.     indent_puts( "++yy_cp;" );
  493.  
  494.     if ( num_backtracking > 0 )
  495.         indent_puts( "}" );
  496.  
  497.     indent_down();
  498.  
  499.     putchar( '\n' );
  500.     indent_puts( "yy_current_state = -yy_current_state;" );
  501.     }
  502.  
  503.     else if ( fullspd )
  504.     {
  505.     indent_puts( "{" );
  506.     indent_puts( "register struct yy_trans_info *yy_trans_info;\n" );
  507.     indent_puts( "register char yy_c;\n" );
  508.     indent_put2s( "for ( yy_c = %s;", char_map );
  509.     indent_puts(
  510.     "      (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" );
  511.     indent_put2s( "      yy_c = %s )", char_map_2 );
  512.  
  513.     indent_up();
  514.  
  515.     if ( num_backtracking > 0 )
  516.         indent_puts( "{" );
  517.  
  518.     indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  519.  
  520.     if ( num_backtracking > 0 )
  521.         {
  522.         putchar( '\n' );
  523.         gen_backtracking();
  524.         indent_puts( "}" );
  525.         }
  526.  
  527.     indent_down();
  528.     indent_puts( "}" );
  529.     }
  530.  
  531.     else
  532.     { /* compressed */
  533.     indent_puts( "do" );
  534.  
  535.     indent_up();
  536.     indent_puts( "{" );
  537.  
  538.     gen_next_state();
  539.  
  540.     indent_puts( "++yy_cp;" );
  541.  
  542.     indent_puts( "}" );
  543.     indent_down();
  544.  
  545.     do_indent();
  546.  
  547.     if ( interactive )
  548.         printf( "while ( yy_base[yy_current_state] != %d );\n", jambase );
  549.     else
  550.         printf( "while ( yy_current_state != %d );\n", jamstate );
  551.  
  552.     if ( ! reject && ! interactive )
  553.         {
  554.         /* do the guaranteed-needed backtrack to figure out the match */
  555.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  556.         indent_puts( "yy_current_state = yy_last_accepting_state;" );
  557.         }
  558.     }
  559.     }
  560.  
  561.  
  562. /* generate the code to find the next state */
  563.  
  564. gen_next_state()
  565.  
  566.     { /* NOTE - changes in here should be reflected in get_next_match() */
  567.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  568.     
  569.     if ( fulltbl )
  570.     {
  571.     indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", 
  572.         char_map );
  573.     gen_backtracking();
  574.     }
  575.  
  576.     else if ( fullspd )
  577.     {
  578.     indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;",
  579.         char_map );
  580.     gen_backtracking();
  581.     }
  582.  
  583.     else
  584.     {
  585.     gen_next_compressed_state();
  586.  
  587.     if ( reject )
  588.         indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  589.     }
  590.     }
  591.  
  592.  
  593. /* generate the code to find the start state */
  594.  
  595. gen_start_state()
  596.  
  597.     {
  598.     if ( fullspd )
  599.     indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",
  600.         bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
  601.  
  602.     else
  603.     {
  604.     indent_puts( "yy_current_state = yy_start;" );
  605.  
  606.     if ( bol_needed )
  607.         {
  608.         indent_puts( "if ( yy_bp[-1] == '\\n' )" );
  609.         indent_up();
  610.         indent_puts( "++yy_current_state;" );
  611.         indent_down();
  612.         }
  613.  
  614.     if ( reject )
  615.         {
  616.         /* set up for storing up states */
  617.         indent_puts( "yy_state_ptr = yy_state_buf;" );
  618.         indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  619.         }
  620.     }
  621.     }
  622.  
  623.  
  624. /* gentabs - generate data statements for the transition tables
  625.  *
  626.  * synopsis
  627.  *    gentabs();
  628.  */
  629.  
  630. gentabs()
  631.  
  632.     {
  633.     int i, j, k, *accset, nacc, *acc_array, total_states;
  634.     int end_of_buffer_action = num_rules + 1;
  635.  
  636.     /* *everything* is done in terms of arrays starting at 1, so provide
  637.      * a null entry for the zero element of all C arrays
  638.      */
  639.     static char C_long_decl[] =
  640.     "static const long int %s[%d] =\n    {   0,\n";
  641.     static char C_short_decl[] =
  642.     "static const short int %s[%d] =\n    {   0,\n";
  643.     static char C_char_decl[] =
  644.     "static const char %s[%d] =\n    {   0,\n";
  645.  
  646.     acc_array = allocate_integer_array( current_max_dfas );
  647.     nummt = 0;
  648.  
  649.     /* the compressed table format jams by entering the "jam state",
  650.      * losing information about the previous state in the process.
  651.      * In order to recover the previous state, we effectively need
  652.      * to keep backtracking information.
  653.      */
  654.     ++num_backtracking;
  655.  
  656.     if ( reject )
  657.     {
  658.     /* write out accepting list and pointer list
  659.      *
  660.      * first we generate the ACCEPT array.  In the process, we compute
  661.      * the indices that will go into the ALIST array, and save the
  662.      * indices in the dfaacc array
  663.      */
  664.     int EOB_accepting_list[2];
  665.  
  666.     printf( C_short_decl, ACCEPT, max( numas, 1 ) + 1 );
  667.     
  668.     /* set up accepting structures for the End Of Buffer state */
  669.     EOB_accepting_list[0] = 0;
  670.     EOB_accepting_list[1] = end_of_buffer_action;
  671.     accsiz[end_of_buffer_state] = 1;
  672.     dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
  673.  
  674.     j = 1;    /* index into ACCEPT array */
  675.  
  676.     for ( i = 1; i <= lastdfa; ++i )
  677.         {
  678.         acc_array[i] = j;
  679.  
  680.         if ( accsiz[i] != 0 )
  681.         {
  682.         accset = dfaacc[i].dfaacc_set;
  683.         nacc = accsiz[i];
  684.  
  685.         if ( trace )
  686.             fprintf( stderr, "state # %d accepts: ", i );
  687.  
  688.         for ( k = 1; k <= nacc; ++k )
  689.             {
  690.             int accnum = accset[k];
  691.  
  692.             ++j;
  693.  
  694.             if ( variable_trailing_context_rules &&
  695.              ! (accnum & YY_TRAILING_HEAD_MASK) &&
  696.              accnum > 0 &&
  697.              rule_type[accnum] == RULE_VARIABLE )
  698.             {
  699.             /* special hack to flag accepting number as part
  700.              * of trailing context rule
  701.              */
  702.             accnum |= YY_TRAILING_MASK;
  703.             }
  704.  
  705.             mkdata( accnum );
  706.  
  707.             if ( trace )
  708.             {
  709.             fprintf( stderr, "[%d]", accset[k] );
  710.  
  711.             if ( k < nacc )
  712.                 fputs( ", ", stderr );
  713.             else
  714.                 putc( '\n', stderr );
  715.             }
  716.             }
  717.         }
  718.         }
  719.  
  720.     /* add accepting number for the "jam" state */
  721.     acc_array[i] = j;
  722.  
  723.     dataend();
  724.     }
  725.  
  726.     else
  727.     {
  728.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  729.  
  730.     for ( i = 1; i <= lastdfa; ++i )
  731.         acc_array[i] = dfaacc[i].dfaacc_state;
  732.  
  733.     /* add accepting number for jam state */
  734.     acc_array[i] = 0;
  735.     }
  736.  
  737.     /* spit out ALIST array.  If we're doing "reject", it'll be pointers
  738.      * into the ACCEPT array.  Otherwise it's actual accepting numbers.
  739.      * In either case, we just dump the numbers.
  740.      */
  741.  
  742.     /* "lastdfa + 2" is the size of ALIST; includes room for C arrays
  743.      * beginning at 0 and for "jam" state
  744.      */
  745.     k = lastdfa + 2;
  746.  
  747.     if ( reject )
  748.     /* we put a "cap" on the table associating lists of accepting
  749.      * numbers with state numbers.  This is needed because we tell
  750.      * where the end of an accepting list is by looking at where
  751.      * the list for the next state starts.
  752.      */
  753.     ++k;
  754.  
  755.     printf( C_short_decl, ALIST, k );
  756.  
  757.     for ( i = 1; i <= lastdfa; ++i )
  758.     {
  759.     mkdata( acc_array[i] );
  760.  
  761.     if ( ! reject && trace && acc_array[i] )
  762.         fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );
  763.     }
  764.  
  765.     /* add entry for "jam" state */
  766.     mkdata( acc_array[i] );
  767.  
  768.     if ( reject )
  769.     /* add "cap" for the list */
  770.     mkdata( acc_array[i] );
  771.  
  772.     dataend();
  773.  
  774.     if ( useecs )
  775.     genecs();
  776.  
  777.     if ( usemecs )
  778.     {
  779.     /* write out meta-equivalence classes (used to index templates with) */
  780.  
  781.     if ( trace )
  782.         fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
  783.  
  784.     printf( C_char_decl, MATCHARRAY, numecs + 1 );
  785.  
  786.     for ( i = 1; i <= numecs; ++i )
  787.         {
  788.         if ( trace )
  789.         fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );
  790.  
  791.         mkdata( abs( tecbck[i] ) );
  792.         }
  793.  
  794.     dataend();
  795.     }
  796.  
  797.     total_states = lastdfa + numtemps;
  798.  
  799.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  800.         BASEARRAY, total_states + 1 );
  801.  
  802.     for ( i = 1; i <= lastdfa; ++i )
  803.     {
  804.     register int d = def[i];
  805.  
  806.     if ( base[i] == JAMSTATE )
  807.         base[i] = jambase;
  808.  
  809.     if ( d == JAMSTATE )
  810.         def[i] = jamstate;
  811.  
  812.     else if ( d < 0 )
  813.         {
  814.         /* template reference */
  815.         ++tmpuses;
  816.         def[i] = lastdfa - d + 1;
  817.         }
  818.  
  819.     mkdata( base[i] );
  820.     }
  821.  
  822.     /* generate jam state's base index */
  823.     mkdata( base[i] );
  824.  
  825.     for ( ++i /* skip jam state */; i <= total_states; ++i )
  826.     {
  827.     mkdata( base[i] );
  828.     def[i] = jamstate;
  829.     }
  830.  
  831.     dataend();
  832.  
  833.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  834.         DEFARRAY, total_states + 1 );
  835.  
  836.     for ( i = 1; i <= total_states; ++i )
  837.     mkdata( def[i] );
  838.  
  839.     dataend();
  840.  
  841.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  842.         NEXTARRAY, tblend + 1 );
  843.  
  844.     for ( i = 1; i <= tblend; ++i )
  845.     {
  846.     if ( nxt[i] == 0 || chk[i] == 0 )
  847.         nxt[i] = jamstate;    /* new state is the JAM state */
  848.  
  849.     mkdata( nxt[i] );
  850.     }
  851.  
  852.     dataend();
  853.  
  854.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  855.         CHECKARRAY, tblend + 1 );
  856.  
  857.     for ( i = 1; i <= tblend; ++i )
  858.     {
  859.     if ( chk[i] == 0 )
  860.         ++nummt;
  861.  
  862.     mkdata( chk[i] );
  863.     }
  864.  
  865.     dataend();
  866.     }
  867.  
  868.  
  869. /* write out a formatted string (with a secondary string argument) at the
  870.  * current indentation level, adding a final newline
  871.  */
  872.  
  873. indent_put2s( fmt, arg )
  874. char fmt[], arg[];
  875.  
  876.     {
  877.     do_indent();
  878.     printf( fmt, arg );
  879.     putchar( '\n' );
  880.     }
  881.  
  882.  
  883. /* write out a string at the current indentation level, adding a final
  884.  * newline
  885.  */
  886.  
  887. indent_puts( str )
  888. char str[];
  889.  
  890.     {
  891.     do_indent();
  892.     puts( str );
  893.     }
  894.  
  895.  
  896. /* make_tables - generate transition tables
  897.  *
  898.  * synopsis
  899.  *     make_tables();
  900.  *
  901.  * Generates transition tables and finishes generating output file
  902.  */
  903.  
  904. make_tables()
  905.  
  906.     {
  907.     register int i;
  908.     int did_eof_rule = false;
  909.  
  910.     printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
  911.  
  912.     if ( fullspd )
  913.     { /* need to define the transet type as a size large
  914.        * enough to hold the biggest offset
  915.        */
  916.     int total_table_size = tblend + numecs + 1;
  917.     char *trans_offset_type =
  918.         total_table_size > MAX_SHORT ? "long" : "short";
  919.  
  920.     set_indent( 0 );
  921.     indent_puts( "struct yy_trans_info" );
  922.     indent_up();
  923.         indent_puts( "{" );
  924.         indent_puts( "short yy_verify;" );
  925.  
  926.         /* in cases where its sister yy_verify *is* a "yes, there is a
  927.      * transition", yy_nxt is the offset (in records) to the next state.
  928.      * In most cases where there is no transition, the value of yy_nxt
  929.      * is irrelevant.  If yy_nxt is the -1th  record of a state, though,
  930.      * then yy_nxt is the action number for that state
  931.          */
  932.  
  933.         indent_put2s( "%s yy_nxt;", trans_offset_type );
  934.         indent_puts( "};" );
  935.     indent_down();
  936.  
  937.     indent_puts( "typedef struct yy_trans_info *yy_state_type;" );
  938.     }
  939.     
  940.     else
  941.     indent_puts( "typedef int yy_state_type;" );
  942.  
  943.     if ( fullspd )
  944.     genctbl();
  945.  
  946.     else if ( fulltbl )
  947.     genftbl();
  948.  
  949.     else
  950.     gentabs();
  951.  
  952.     if ( reject )
  953.     {
  954.     /* declare state buffer variables */
  955.     puts( "yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
  956.     puts( "char *yy_full_match;" );
  957.     puts( "int yy_lp;" );
  958.  
  959.     if ( variable_trailing_context_rules )
  960.         {
  961.         puts( "int yy_looking_for_trail_begin = 0;" );
  962.         puts( "int yy_full_lp;" );
  963.         puts( "int *yy_full_state;" );
  964.         printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK );
  965.         printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
  966.             YY_TRAILING_HEAD_MASK );
  967.         }
  968.  
  969.     puts( "#define REJECT \\" );
  970.         puts( "{ \\" );
  971.         puts(
  972.     "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
  973.         puts(
  974.         "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
  975.  
  976.     if ( variable_trailing_context_rules )
  977.         {
  978.         puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
  979.         puts(
  980.         "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
  981.         puts(
  982.         "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
  983.         }
  984.  
  985.         puts( "++yy_lp; \\" );
  986.         puts( "goto find_rule; \\" );
  987.         puts( "}" );
  988.     }
  989.     
  990.     else
  991.     {
  992.     puts( "/* the intent behind this definition is that it'll catch" );
  993.     puts( " * any uses of REJECT which flex missed" );
  994.     puts( " */" );
  995.     puts( "#define REJECT reject_used_but_not_detected" );
  996.     }
  997.     
  998.     if ( yymore_used )
  999.     {
  1000.     indent_puts( "static char *yy_more_pos = (char *) 0;" );
  1001.     indent_puts( "#define yymore() (yy_more_pos = yy_bp)" );
  1002.     }
  1003.     
  1004.     else
  1005.     indent_puts( "#define yymore() yymore_used_but_not_detected" );
  1006.  
  1007.  
  1008.     skelout();
  1009.  
  1010.     (void) fclose( temp_action_file );
  1011.     temp_action_file = fopen( action_file_name, "r" );
  1012.  
  1013.     /* copy prolog from action_file to output file */
  1014.     action_out();
  1015.  
  1016.     skelout();
  1017.  
  1018.     set_indent( 2 );
  1019.  
  1020.     if ( yymore_used )
  1021.     {
  1022.     indent_puts( "if ( yy_more_pos )" );
  1023.     indent_up();
  1024.     indent_puts( "{" );
  1025.     indent_puts( "yy_bp = yy_more_pos;" );
  1026.     indent_puts( "yy_more_pos = (char *) 0;" );
  1027.     indent_puts( "}" );
  1028.     indent_down();
  1029.     indent_puts( "else" );
  1030.     indent_up();
  1031.     indent_puts( "yy_bp = yy_cp;" );
  1032.     indent_down();
  1033.     }
  1034.  
  1035.     else
  1036.     indent_puts( "yy_bp = yy_cp;" );
  1037.  
  1038.     skelout();
  1039.  
  1040.     gen_start_state();
  1041.     gen_next_match();
  1042.  
  1043.     skelout();
  1044.     set_indent( 3 );
  1045.     gen_find_action();
  1046.  
  1047.     /* copy actions from action_file to output file */
  1048.     skelout();
  1049.     indent_up();
  1050.     gen_bt_action();
  1051.     action_out();
  1052.  
  1053.     /* generate cases for any missing EOF rules */
  1054.     for ( i = 1; i <= lastsc; ++i )
  1055.     if ( ! sceof[i] )
  1056.         {
  1057.         do_indent();
  1058.         printf( "case YY_STATE_EOF(%s):\n", scname[i] );
  1059.         did_eof_rule = true;
  1060.         }
  1061.     
  1062.     if ( did_eof_rule )
  1063.     {
  1064.     indent_up();
  1065.     indent_puts( "yyterminate();" );
  1066.     indent_down();
  1067.     }
  1068.  
  1069.  
  1070.     /* generate code for yy_get_previous_state() */
  1071.     set_indent( 1 );
  1072.     skelout();
  1073.  
  1074.     if ( bol_needed )
  1075.     indent_puts( "register char *yy_bp = yytext;\n" );
  1076.  
  1077.     gen_start_state();
  1078.  
  1079.     set_indent( 2 );
  1080.     skelout();
  1081.     gen_next_state();
  1082.  
  1083.     skelout();
  1084.  
  1085.     /* copy remainder of input to output */
  1086.  
  1087.     line_directive_out( stdout );
  1088.     (void) flexscan(); /* copy remainder of input to output */
  1089.     }
  1090.  
  1091.  
  1092.